#!/usr/bin/perl -w
# Used to pipe sentences into the postagger and pipe out
# tagged text.

use strict;
use warnings;

use IPC::Open3;
use IO::Select;

my $rio = IO::Select->new();
my $eio = IO::Select->new();

my($rdr, $wrt, $err);

my($pid) = 0;
sub postPipeBegin
{
	#print "Opening pipes";
	
	chdir "postagger";
	$pid = open3($wrt, $rdr, $err, './tagger') 
		or die "ERROR:  Couldn't call open3\n";
	chdir "..";
	
	#print "Process ID is $pid\n";
	#print "Adding file handles to IO Selecters\n";
	
	## add the reader and the err file handles to their own IO::Selects
	## so that we can easily determine later whether they are ready to be read
	$rio->add($rdr);
	$eio->add($err);
	
	# turn on autoflushing for the writer file handle
	#$wrt->autoflush(1);
	select($wrt);
	$| = 1;
	select(STDOUT);
	
	## read the loading messages as the occur
	for (0..15)
	{
		if(!($_=postRead(10))) ## long delay because loading can be slow
		{
			print "Error!  Loading message failed to occur.\n";
			exit;
		}
		else
		{
			## print the loading message so the user knows that we are actually 
			## doing something
			print $_;
		}
	} 
	if(postCanReadErr())
	{
		print "An error arose!\n";
		exit;
	}
	
	#print "Init done\n";
}

sub postPipeClose
{
	close $wrt;
	close $rdr;
	#close $err;
}

sub postWrite
{
	my $msg = shift;
	print $wrt $msg;
}

sub postCanRead
{
	# get optional timeout length
	my $len = shift;
	#if(!defined($len)){	$len = 0.1;	}
	
	my @readable = $rio->can_read($len);
	# see whether post's STDIN is ready for read
	if(@readable)
	{
		#print "readable (STDIN,YES): {{$#readable}}\n";
		return 1;
	}
	else
	{
		#print "readable (STDIN,NO): {{$#readable}}\n";
	}
	return 0;
}
sub postRead
{
	# timeout wait
	my $timeout = shift;
	
	my $msg = undef;
	if(postCanRead($timeout))
	{
		#$msg = <$rdr>;
		$msg = readline($rdr);
		
		#my ($count, $data); 
		#$count = sysread($rdr, $data, 50); 

		# Business as usual. 
		#print "read data: '$data'\n"; 
		#$msg =$data;
	}
	return $msg;
}

sub postCanReadErr
{
	# get optional timeout length
	my($len);
	$len = shift;
	if(!defined($len)){$len = 0.1;}
	
	my @readable = $eio->can_read($len);
	# see whether post's STDERR is ready for read
	if(@readable)
	{
		#print "readable (STDERR,YES): {{$#readable}}\n";
		return 1;
	}
	else
	{
		#print "readable (STDERR,NO): {{$#readable}}\n";
	}
	return 0;
}
sub postReadErr
{
	#timeout wait
	my $timeout = shift;	
	my $msg = undef;
	
	if(postCanReadErr($timeout))
	{
		$msg = <$err>;
	}
	return $msg;
}

sub postTest
{
	print "Begin postagger Test\n";

	## check for anything waiting on the inlines that might indicate some error
	while(postCanRead(0.1) || postCanReadErr(0.1))
	{
		if(postCanRead())
		{
			print "Can read STDIN: \"" . postRead() . "\"\n";
		}
		if(postCanReadErr())
		{
			print "Can read STDERR: \"" . postReadErr() . "\"\n";
		}	
	}
	
	## send postagger our test message
	my $testmsg = "The quick brown fox jumped over the fat lazy dog.\n".
						"What is your name?\nMy name is Bob!\n";
	print "input:\n===\n\"$testmsg\"\n===\n";
	postWrite($testmsg);
	
	## we sent 3 lines so we are expecting 3 lines back
	for (1..3)
	{
		my $read = "";
		if(!($read = postRead(5)))
		{
			print "Could not read on loop $_\n";
		}
		else
		{
			print "read: '$read'\n";
		}
	}
	
	print "postagger Test Done!\n";
}
postPipeBegin();

#postTest();

1; # stops perl from complaining when this script is included

